The present invention relates generally to object-based high level programming environments, and more particularly, to virtual machine instruction sets suitable for execution in virtual machines operating in portable, platform independent programming environments Recently, the Java™ programming environment has become quite popular. The Java™ programming language is a language that is designed to be portable enough to be executed on a wide range of computers ranging from small devices (e.g., pagers, cell phones and smart cards) up to supercomputers. Computer programs written in the Java programming language (and other languages) may be compiled into Java Bytecode instructions that are suitable for execution by a Java virtual machine implementation.
The Java virtual machine is commonly implemented in software by means of an interpreter for the Java virtual machine instruction set but, in general, may be software, hardware, or both. A particular Java virtual machine implementation and corresponding support libraries, together constitute a Java™ runtime environment.
Computer programs in the Java programming language are arranged in one or more classes or interfaces (referred to herein jointly as classes or class files). Such programs are generally platform, i.e., hardware and operating system, independent. As such, these computer programs may be executed without modification, on any computer that is able to run an implementation of the Java™ runtime environment. A class written in the Java programming language is compiled to a particular binary format called the “class file format” that includes Java virtual machine instructions for the methods of a single class. In addition to the Java virtual machine instructions for the methods of a class, the class file format includes a significant amount of ancillary information that is associated with the class. The class file format (as well as the general operation of the Java virtual machine) is described in some detail in The Java Virtual Machine Specification by Tim Lindholm and Frank Yellin (ISBN 0-201-31006-6), which is hereby incorporated herein by reference.
Conventional virtual machines interpreter decodes and executes the Java Bytecode instructions, one instruction at a time during execution, e.g., “at runtime.” To execute a Java instruction, typically, several operations have to been performed to obtain the information that is necessary to execute the Java instruction. For example, to invoke a method referenced by a Java bytecode, the virtual machine must perform several operations to access the Constant Pool simply to identify the information necessary to locate and access the invoked method.
As described in The Java Virtual Machine Specification, one of the structures of a standard class file is known as the “Constant Pool.” The Constant Pool is a data structure that has several uses. One of the uses of the Constant Pool that is relevant to the present invention is that the Constant Pool contains the information that is needed to resolve various Java Instructions. To illustrate, FIG. 1 depicts a conventional computing environment 100 including a stream of Java Bytecodes 102, a constant pool 104 and an execution stack 106. The stream of Java Bytecodes 102 represents a series of bytes in a stream where one or more bytes can represent a Java Bytecode instruction. For example, a byte 108 can represent a Ldc (load constant on the execution stack) Bytecode command 108. Accordingly, the bytes 110 and 112 represent the parameters for the Ldc Bytecode command 108. In this case, these bytes respectively represent a CP-IndexA 100 and CP-IndexB 112 that collectively represent the index to appropriate constant value in the constant pool 104. For example, bytes C1, C2, C3 and C4 of the constant pool 104 can collectively represent the appropriate 4 byte (one word) constant C that is to loaded to the top of the execution stack 106. It should be noted that Ldc Bytecode command 108 and its parameters represented by bytes 110 and 112 are collectively referred to herein as a Java Bytecode instruction.
In order to execute the Java Bytecode Ldc Instruction 108, at run time, an index to the Constant Pool 104 is constructed from the CP-IndexA and CP-IndexA. Once an index to the Constant Pool has been determined, the appropriate structures in the Constant Pool have to be accessed so that the appropriate constant value can be determined. Accordingly, the Java Bytecode Ldc instruction can be executed only after performing several operations at run time. As can be appreciated from the example above, the execution of a relatively simple instruction such as loading a constant value can take a significant amount of run time. Hence, this conventional technique is an inefficient approach that may result in significantly longer execution times.
Another problem is that the conventional Java Bytecode instruction set has more than 220 instructions. Moreover, there is a significant amount of redundancy between some instructions in the conventional Java Bytecode instruction set. For example, there are different Java Bytecode instructions for storing (or pushing) integer local variables on the execution stack (e.g., iLoad), and storing (or pushing) a pointer local variable on the execution stack (e.g., aLoad). However, the operations performed by these instructions are virtually identical, namely, storing (or pushing) 4 byte values (a word) on the execution stack. There is also a significant amount of overlap between some instructions of the conventional Java Bytecode instruction set. For example, there are 5 different Java Bytecode instructions for pushing one byte integer values on the execution stack (i.e., iconst—1, iconst—2, iconst—3, iconst—4 and iconst—5). However, these operations virtually perform the same operations, namely, pushing a constant one byte integer value on the execution stack.
As noted above, the Java Bytecode instruction set has more than 220 instructions. This means that conventionally nearly all of the 256 (28) allowable Bytecode values have to be assigned to Java instructions (commands or opcodes). As a result, Java interpreters are needlessly complex since they need to recognize a relatively large number of Java instructions and possibly implement various mechanisms for executing many instructions. Thus, the conventional Java Bytecode instruction set is not a very desirable solution for systems with limited resources (e.g., embedded systems)
Accordingly, there is a need for alternative instructions suitable for execution in virtual machines.